<HTML>
<HEAD>
<TITLE>
BeanManager.cpp
</TITLE>
</HEAD>
<BODY>
<PRE>
<font color="green">/*
* Copyright 2006 the original author or authors.
* 
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* 
*      http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/</font>

<font color="blue">#include</font> <font color="maroon">"ValueWrapper.h"</font>
<font color="blue">#include</font> <font color="maroon">"BeanManager.h"</font>
<font color="blue">#include</font> <font color="maroon">"AutumnLog.h"</font>

<font color="green">/** 
 * Maintains all created beans and dependence ralations in them.
 * @version 0.1.0
 * @since 2006-12-18
 */</font>

<font color="blue">namespace</font> Autumn<font color="black">{</font>

<font color="blue">const</font> <font color="blue">int</font> BeanManager<font color="black">:</font><font color="black">:</font>HashDivisor <font color="black">=</font> <font color="maroon">997</font>;

BeanManager<font color="black">:</font><font color="black">:</font>~BeanManager<font color="black">(</font><font color="black">)</font>
<font color="black">{</font>
    <font color="blue">typedef</font> <font color="blue">void</font> WrapperFreer <font color="black">(</font>IBeanWrapper<font color="black">*</font><font color="black">)</font>;
    map<font color="black">&#60;</font><font color="blue">long</font>, <font color="blue">long</font><font color="black">&#62;</font> m;
    vector<font color="black">&#60;</font>IBeanWrapper<font color="black">*</font><font color="black">&#62;</font> vSingleton;
    IBeanWrapper<font color="black">*</font> pt;
    WrapperFreer<font color="black">*</font> pf;
    
    AutumnLog<font color="black">:</font><font color="black">:</font>getInstance<font color="black">(</font><font color="black">)</font><font color="black">-</font><font color="black">&#62;</font>debug<font color="black">(</font><font color="maroon">"BeanManager-&#62;~BeanManager"</font><font color="black">)</font>;
    
    <font color="blue">this</font><font color="black">-</font><font color="black">&#62;</font>Beans.listElement<font color="black">(</font>m<font color="black">)</font>;
    <font color="blue">for</font><font color="black">(</font>map<font color="black">&#60;</font><font color="blue">long</font>, <font color="blue">long</font><font color="black">&#62;</font><font color="black">:</font><font color="black">:</font>iterator it <font color="black">=</font> m.begin<font color="black">(</font><font color="black">)</font>; it <font color="black">!</font><font color="black">=</font> m.end<font color="black">(</font><font color="black">)</font>; it<font color="black">+</font><font color="black">+</font><font color="black">)</font><font color="black">{</font>
        <font color="blue">long</font> tmp;
        <font color="blue">this</font><font color="black">-</font><font color="black">&#62;</font>Beans.deleteElement<font color="black">(</font>it<font color="black">-</font><font color="black">&#62;</font>first, tmp<font color="black">)</font>;
        
        pt <font color="black">=</font> <font color="black">(</font>IBeanWrapper <font color="black">*</font><font color="black">)</font>it<font color="black">-</font><font color="black">&#62;</font>second;

        <font color="green">// Singleton will be deleted at last</font>
        <font color="blue">if</font><font color="black">(</font> pt<font color="black">-</font><font color="black">&#62;</font>getSingleton<font color="black">(</font><font color="black">)</font> <font color="black">)</font> <font color="black">{</font>
            vSingleton.push_back<font color="black">(</font>pt<font color="black">)</font>;
        <font color="black">}</font>
        <font color="blue">else</font><font color="black">{</font>
            pf <font color="black">=</font> pt<font color="black">-</font><font color="black">&#62;</font>getWrapperDeleter<font color="black">(</font><font color="black">)</font>;
            pf<font color="black">(</font>pt<font color="black">)</font>;     <font color="green">//delete itself</font>
        <font color="black">}</font>
    <font color="black">}</font>

    <font color="blue">for</font><font color="black">(</font> <font color="blue">int</font> i<font color="black">=</font><font color="maroon">0</font>; i<font color="black">&#60;</font>vSingleton.size<font color="black">(</font><font color="black">)</font>; i<font color="black">+</font><font color="black">+</font><font color="black">)</font><font color="black">{</font>
        pt <font color="black">=</font> vSingleton<font color="black">[</font>i<font color="black">]</font>;
        pf <font color="black">=</font> pt<font color="black">-</font><font color="black">&#62;</font>getWrapperDeleter<font color="black">(</font><font color="black">)</font>;
        pf<font color="black">(</font>pt<font color="black">)</font>;     <font color="green">//delete itself</font>
    <font color="black">}</font>
<font color="black">}</font>
<font color="green">/** 
 * Delete a bean from bean manager.
 * @param p Pointer to the bean.
 */</font>
<font color="blue">void</font> BeanManager<font color="black">:</font><font color="black">:</font>deleteBean<font color="black">(</font><font color="blue">void</font><font color="black">*</font> p<font color="black">)</font>
<font color="black">{</font>
    TPointer pw;
    <font color="blue">typedef</font> <font color="blue">void</font> WrapperFreer <font color="black">(</font>IBeanWrapper<font color="black">*</font><font color="black">)</font>;
    
    AutumnLog<font color="black">:</font><font color="black">:</font>getInstance<font color="black">(</font><font color="black">)</font><font color="black">-</font><font color="black">&#62;</font>debug<font color="black">(</font><font color="maroon">"BeanManager-&#62;deleteBean"</font><font color="black">)</font>;

    <font color="green">// Delete from hash table</font>
    <font color="green">// Maybe it has deleted somewhere, like ~BeanManager()</font>
    <font color="blue">if</font><font color="black">(</font> <font color="blue">this</font><font color="black">-</font><font color="black">&#62;</font>Beans.deleteElement<font color="black">(</font><font color="black">(</font>TPointer<font color="black">)</font>p, pw<font color="black">)</font> <font color="black">)</font><font color="black">{</font>
        IBeanWrapper<font color="black">*</font> pt <font color="black">=</font> <font color="black">(</font>IBeanWrapper <font color="black">*</font><font color="black">)</font>pw;
        
        <font color="green">// Singleton will be deleted at last</font>
        <font color="blue">if</font><font color="black">(</font> <font color="black">!</font> pt<font color="black">-</font><font color="black">&#62;</font>getSingleton<font color="black">(</font><font color="black">)</font> <font color="black">)</font> <font color="black">{</font>
            WrapperFreer<font color="black">*</font> pf <font color="black">=</font> pt<font color="black">-</font><font color="black">&#62;</font>getWrapperDeleter<font color="black">(</font><font color="black">)</font>;
            pf<font color="black">(</font>pt<font color="black">)</font>;     <font color="green">//delete itself</font>
        <font color="black">}</font>
    <font color="black">}</font>
<font color="black">}</font>

IBeanWrapper<font color="black">*</font> BeanManager<font color="black">:</font><font color="black">:</font>releaseBean<font color="black">(</font><font color="blue">void</font><font color="black">*</font> p<font color="black">)</font><font color="black">{</font>
    TPointer pw <font color="black">=</font> <font color="black">(</font>TPointer<font color="black">)</font>NULL;
    <font color="blue">this</font><font color="black">-</font><font color="black">&#62;</font>Beans.deleteElement<font color="black">(</font><font color="black">(</font>TPointer<font color="black">)</font>p, pw<font color="black">)</font>;
    <font color="blue">this</font><font color="black">-</font><font color="black">&#62;</font>deleteSingleton<font color="black">(</font>p<font color="black">)</font>;
    <font color="blue">return</font> <font color="black">(</font>IBeanWrapper<font color="black">*</font><font color="black">)</font>pw;
<font color="black">}</font>

IBeanWrapper<font color="black">*</font> BeanManager<font color="black">:</font><font color="black">:</font>getBeanWrapper<font color="black">(</font><font color="blue">void</font><font color="black">*</font> p<font color="black">)</font> <font color="blue">const</font> <font color="black">{</font>
    TPointer pw <font color="black">=</font> <font color="black">(</font>TPointer<font color="black">)</font>NULL;
    <font color="blue">this</font><font color="black">-</font><font color="black">&#62;</font>Beans.searchElement<font color="black">(</font><font color="black">(</font>TPointer<font color="black">)</font>p, pw<font color="black">)</font>;
    <font color="blue">return</font> <font color="black">(</font>IBeanWrapper<font color="black">*</font><font color="black">)</font>pw;
<font color="black">}</font>

<font color="green">/** 
 * Add a bean
 * @param name Bean's name
 * @param pw Pointer to bean's wrapper
 */</font>
<font color="blue">void</font> BeanManager<font color="black">:</font><font color="black">:</font>addBean<font color="black">(</font><font color="blue">const</font> string<font color="black">&</font> <font color="blue">name</font>, IBeanWrapper<font color="black">*</font> pw<font color="black">)</font>
<font color="black">{</font>
    TPointer pl <font color="black">=</font> <font color="black">(</font>TPointer<font color="black">)</font>pw;
    <font color="blue">this</font><font color="black">-</font><font color="black">&#62;</font>Beans.insertElement<font color="black">(</font><font color="black">(</font>TPointer<font color="black">)</font>pw<font color="black">-</font><font color="black">&#62;</font>getBean<font color="black">(</font><font color="black">)</font>, pl<font color="black">)</font>;

    <font color="blue">if</font><font color="black">(</font> pw<font color="black">-</font><font color="black">&#62;</font>getSingleton<font color="black">(</font><font color="black">)</font> <font color="black">)</font>
        <font color="blue">this</font><font color="black">-</font><font color="black">&#62;</font>SingletonBeans.insert<font color="black">(</font>make_pair<font color="black">(</font><font color="blue">name</font>, pw<font color="black">-</font><font color="black">&#62;</font>getBean<font color="black">(</font><font color="black">)</font><font color="black">)</font><font color="black">)</font>;
<font color="black">}</font>

<font color="green">/** 
 * Find a singleton by name
 */</font>
<font color="blue">void</font><font color="black">*</font> BeanManager<font color="black">:</font><font color="black">:</font>getSingleton<font color="black">(</font><font color="blue">const</font> string<font color="black">&</font> <font color="blue">name</font><font color="black">)</font><font color="blue">const</font>
<font color="black">{</font>
    map<font color="black">&#60;</font>string, <font color="blue">void</font><font color="black">*</font><font color="black">&#62;</font><font color="black">:</font><font color="black">:</font>const_iterator it <font color="black">=</font> <font color="blue">this</font><font color="black">-</font><font color="black">&#62;</font>SingletonBeans.find<font color="black">(</font><font color="blue">name</font><font color="black">)</font>;
    <font color="blue">if</font><font color="black">(</font> it <font color="black">!</font><font color="black">=</font> <font color="blue">this</font><font color="black">-</font><font color="black">&#62;</font>SingletonBeans.end<font color="black">(</font><font color="black">)</font> <font color="black">)</font>
        <font color="blue">return</font> it<font color="black">-</font><font color="black">&#62;</font>second;

    <font color="blue">return</font> NULL;
<font color="black">}</font>

<font color="green">/** 
 * Delete a singleton by pointer 
 */</font>
<font color="blue">void</font> BeanManager<font color="black">:</font><font color="black">:</font>deleteSingleton<font color="black">(</font><font color="blue">void</font><font color="black">*</font> p<font color="black">)</font>
<font color="black">{</font>
    <font color="blue">for</font><font color="black">(</font>map<font color="black">&#60;</font>string, <font color="blue">void</font><font color="black">*</font><font color="black">&#62;</font><font color="black">:</font><font color="black">:</font>iterator it <font color="black">=</font> <font color="blue">this</font><font color="black">-</font><font color="black">&#62;</font>SingletonBeans.begin<font color="black">(</font><font color="black">)</font>;
            it <font color="black">!</font><font color="black">=</font> <font color="blue">this</font><font color="black">-</font><font color="black">&#62;</font>SingletonBeans.end<font color="black">(</font><font color="black">)</font>; it<font color="black">+</font><font color="black">+</font><font color="black">)</font><font color="black">{</font>
        <font color="blue">if</font><font color="black">(</font> it<font color="black">-</font><font color="black">&#62;</font>second <font color="black">=</font><font color="black">=</font> p<font color="black">)</font><font color="black">{</font>
            <font color="blue">this</font><font color="black">-</font><font color="black">&#62;</font>SingletonBeans.erase<font color="black">(</font> it <font color="black">)</font>;
            <font color="blue">break</font>;
        <font color="black">}</font>
    <font color="black">}</font>
<font color="black">}</font>

<font color="black">}</font> <font color="green">// End namespace Autumn</font>

</PRE>
</BODY>
</HTML>
